package com.lun.medium;

import java.util.ArrayList;
import java.util.List;

import com.lun.util.BinaryTree.TreeNode;

public class LowestCommonAncestorOfABinaryTree {
	
    @SuppressWarnings("unchecked")
	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		List<TreeNode>[] paths = new List[2];
		List<TreeNode> path = new ArrayList<>();
		find(root, p, q, path, paths);
		
		int step = Math.min(paths[0].size(), paths[1].size());
		TreeNode result = null;
		
		for(int i = 0 ; i < step; i++) {
			if(paths[0].get(i) != paths[1].get(i)) 
				break;
			result = paths[0].get(i);
		}
		return result;
    }
    
    private void find(TreeNode node, TreeNode p, TreeNode q, List<TreeNode> path, List<TreeNode>[] paths) {
    	if(node == null || paths[0] != null && paths[1] != null)
    		return;
    	
    	path.add(node);
    	
    	if(node.val == p.val || node.val == q.val) {
    		if(paths[0] == null) {
    			paths[0] = new ArrayList<>(path);
    		}else if(paths[1] == null){
    			paths[1] = new ArrayList<>(path);
    			return;
    		}
    	}
    	
    	find(node.left, p, q, path, paths);
    	find(node.right, p, q, path, paths);
    	
    	path.remove(path.size() - 1);
    	
    }
    
    public TreeNode lowestCommonAncestor2(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root.val == p.val || root.val == q.val)  return root;
        TreeNode left = lowestCommonAncestor2(root.left, p, q);
        TreeNode right = lowestCommonAncestor2(root.right, p, q);
        if(left != null && right != null)   
        	return root;
        return left != null ? left : right;
    }
    
    
}
